package com.zshy.base.mq.core;

import com.zshy.base.core.context.BaseContext;
import com.zshy.base.core.context.SpringContext;
import com.zshy.base.core.context.ThreadContext;
import com.zshy.base.core.contract.constant.ContextConstants;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;

import java.io.Serializable;
import java.util.List;
import java.util.function.Consumer;

/**
 * MQ消息事件
 *
 * @author win11
 */
@Data
public class MQEvent implements Serializable {
    /**
     * 消息ID，默认当前时间戳
     */
    protected String msgId;
    /**
     * 主题，配置base-mq.producer.topic后无须每次指定
     */
    protected String topic;
    /**
     * 标签，只支持单个标签，多标签需要分开发送
     */
    protected String tag;
    /**
     * 租户ID，默认从线程上下文获取
     */
    protected String tenantId;


    /**
     * 策略匹配，supports参数来源于@MQEventListener.supports
     *
     * @param supports supports
     * @return 是否匹配
     */
    public boolean supports(List<String> supports) {
        return supports.contains(match());
    }

    /**
     * 策略匹配项
     *
     * @return
     */
    public String match() {
        return "*";
    }

    /**
     * 发布MQ事件
     */
    public void publish() {
        this.publish(getTopic(), getTag(), getTenantId());
    }

    /**
     * 发布MQ事件
     *
     * @param topic
     */
    public void publish(String topic) {
        this.publish(topic, getTag(), getTenantId());
    }

    /**
     * 发布MQ事件
     */
    public void publish(String topic, String tag) {
        this.publish(topic, tag, getTenantId());
    }

    /**
     * 发布MQ事件
     *
     * @param topic    主题
     * @param tag      标签
     * @param tenantId 租户ID
     */
    public void publish(String topic, String tag, String tenantId) {
        setTopic(topic);
        if (StringUtils.isBlank(getTopic())) {
            setTopic(SpringContext.getEnv().getProperty("zshy.base.mq.default-topic", "DEFAULT"));
        }
        setTag(tag);
        setTenantId(StringUtils.isNotBlank(tenantId) ? tenantId : ThreadContext.get(ContextConstants.TENANT_ID));
        //todo 有可能出现并发
        setMsgId(StringUtils.isBlank(getMsgId()) ? String.valueOf(System.currentTimeMillis()) : getMsgId());
        if (BaseContext.contains("MQEventPublisher")) {
            ((Consumer<MQEvent>) BaseContext.get("MQEventPublisher")).accept(this);
        }
    }

    public <T extends MQEvent> T tenantId(String tenantId) {
        this.tenantId = tenantId;
        return (T) this;
    }

}